package Market;

import java.io.*;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: Ratuil
 * Date: 06.03.13
 * Time: 15:44
 * To change this template use File | Settings | File Templates.
 */
public class Market implements Serializable{
    private ArrayList<Object>store;
    private ArrayList<MarketStore.Employee>employees;
    private HashMap<String,LinkedList<MarketStore.Product>>categories;
    private List<MarketStore.Product>products;
    private List<MarketStore.Sale>sales;
    MarketStore storage;
    boolean isEmpty;

    Market(){
        isEmpty = !loadDataSerializable();
        store = (ArrayList<Object>) storage.getStore();
        employees=(ArrayList<MarketStore.Employee>)store.get(0);
        categories=(HashMap<String,LinkedList<MarketStore.Product>>)store.get(1);
        sales=(ArrayList<MarketStore.Sale>)store.get(2);
    }

    public void addEmployee(String n,double s,int year,int month,int day){
        MarketStore.Employee newEmployee=new MarketStore.Employee(n,s,year, month, day);
        for(MarketStore.Employee e:employees)
            if(newEmployee.equals(e)){
                System.out.println("Such employee already exist");
                return;
            }
        employees.add(newEmployee);
    }
    public void removeEmployee(int index){
        if(index==0){System.out.println("нелзя уволить Шефа");return;}
        int i=0;
        for(MarketStore.Employee e:employees){
            if(index==i){
                System.out.println("Employee:"+e.getName()+" is removed");
                employees.remove(e);
                return;
            }
        i++;
        }
        System.out.println("No such index of Employee. See list of employee to find index value");
    }
    public void getEmployees(){
        int i=0;
        for(MarketStore.Employee e:employees){
            System.out.println(i+". "+e.toString());
            i++;
        }
    }
    public MarketStore.Employee getEmployee(String name){
        for(MarketStore.Employee e:employees)
            if(name.equals(e.name))
                return e;
        return null;
    }

    public boolean isEmployee(String name){
        for(MarketStore.Employee e:employees)
            if(name.equals(e.name))
                return true;
        return false;
    }

    public void addCategory(String name){
        if(categories.containsKey(name)){
            System.out.println("Such category already exists");
            return;
        }else categories.put(name,new LinkedList<MarketStore.Product>());
        System.out.println("New category successfully added");
    }
    public void removeCategory(String category){
        if(categories.containsKey(category)){
            categories.remove(category);
            System.out.println("Category: "+category+" successfully removed");
        }
        else System.out.println("No such category");
    }
    public void getCategories(){
        for(String s:categories.keySet())
            System.out.println(s);
    }
    public boolean isCategory(String category){
        if(categories.containsKey(category))return true;
        else return false;
    }
    public boolean isProduct(String category,String product){
        if(isCategory(category)){
            for(MarketStore.Product p:categories.get(category))
                if(p.getName().equals(product))
                    return true;
        }
        return false;
    }

    public boolean isEnoughNumber(String category,String product,int number){
        if(isCategory(category)&&isProduct(category,product)){
            for(MarketStore.Product p:categories.get(category))
                if(p.getName().equals(product)&&p.getNumber()>=number)
                    return true;
        }
        return false;
    }

    public void addProduct(String category,String name,double price,int number){
        if(categories.containsKey(category)){
            products=categories.get(category);
            MarketStore.Product newProduct=new MarketStore.Product(name,price, number);
            for(MarketStore.Product p:products){
                if(p.equals(newProduct)){
                    p.setNumber(p.getNumber()+newProduct.getNumber());
                    break;
                }
            }
            products.add(newProduct);
        }else System.out.println("no such category, add it or choose another");
    }
    public void removeProductAll(String category,String product){
        if(isCategory(category)){
            boolean f=false;
            if(isProduct(category,product)){
                products=categories.get(category);
                for(MarketStore.Product p:products)
                    if(p.getName().equals(product)){
                        products.remove(p);
                        System.out.println("Products successfully removed");
                        return;
                    }
            }
            System.out.println("No such product in category");
        }else System.out.println("No such category");
    }
    public void getProducts(String category){
        if(categories.containsKey(category)){
            for(MarketStore.Product p:categories.get(category)){
                System.out.println(p.toString());
            }
        }else System.out.println("No such category");
    }
    public void getProducts(){
        for(String s:categories.keySet())
            for(MarketStore.Product p:categories.get(s)) {}
    }
    public MarketStore.Product getProduct(String category,String product){
        if(isCategory(category)&&isProduct(category,product)){
            for(MarketStore.Product p:categories.get(category))
                if(p.getName().equals(product))
                    return p;
        }
        return null;
    }

    public void sell(String employee,String category,String product,int number){
        MarketStore.Employee e=getEmployee(employee);
        MarketStore.Product p=getProduct(category,product);
        MarketStore.Sale newSale=new MarketStore.Sale(e,p,number);
        sales.add(newSale);
        e.sellCount+=p.getPrice()*number;
        System.out.println("Sale complete");
    }

    public void getSelling(){
        for(MarketStore.Sale s:sales)
            System.out.println(s.toString());
    }

    public void top10(){
        MarketStore.Sale saleTmp=null;
        LinkedList<MarketStore.Sale>salesTmp=new LinkedList<MarketStore.Sale>(sales);
        for(int index=10,max=0;index>0;index--,max=0){
            for(MarketStore.Sale s:salesTmp){
                if(s.number>max){
                    max = s.number;
                    saleTmp = s;
                }
            }
            System.out.println("Top"+index+": "+saleTmp.product.toString());
            salesTmp.remove(saleTmp);
        }
    }


    public void bestEmployee(){
        double max=0;
        for(MarketStore.Employee e:employees)
            if(max<e.sellCount)max=e.sellCount;
        for(MarketStore.Employee e:employees)
            if(e.sellCount==max){
                System.out.println("Best Employee is "+e.name+" - "+e.sellCount);
                break;
            }
    }

    /**
     * Save Market DB on disk
     * If If an exception is thrown - terminate
     */
    protected void saveDataSerializable(){
        try{
            Scanner sc=new Scanner(System.in);
            File file=new File("storage.dat");
            file.delete();
            file.createNewFile();
            long timeout= System.currentTimeMillis();
            ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(file));
            out.writeObject(storage);
            out.close();
            timeout = System.currentTimeMillis() - timeout;
            System.out.println("Saving successful: "+(double)timeout/1000+" s.");
        }catch (Exception e) {
            System.out.println("Erorr save");
            e.printStackTrace();
            System.exit(1);
        }
    }

    /**
     * Load Market DB from disk, if no DB found -
     * throws exception and terminate
     */
    private boolean loadDataSerializable(){
        try{
            File file=new File("storage.dat");
            if(!file.exists()){
                System.out.println("no load file.");
                storage=new MarketStore();
                return false;
            }
            ObjectInputStream in=new ObjectInputStream(new FileInputStream(file));
            storage=(MarketStore)in.readObject();
            return true;
        }catch (Exception e) {
            System.out.println("Erorr load");
            System.exit(1);
            return false;// но зачем?
        }
    }
}
